package com.htjx.mall.commons.utils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class MathUtil {

	/**
	 * @描述:求组合C(n,r)
	 * @param n
	 * @param r
	 * @return
	 */
	final static public int getCombinationCount(int n,int r){
		if(r > n) return 0;
		if(r < 0 || n < 0) return 0;
		return getFactorial(n).divide(getFactorial(r),BigDecimal.ROUND_HALF_DOWN).divide(getFactorial((n-r)),BigDecimal.ROUND_HALF_DOWN).intValue();
	}
	/**
	 * @描述:求n的阶乘
	 * @param n
	 * @return
	 */
	final static public BigDecimal getFactorial(int num) {
        BigDecimal sum = new BigDecimal(1.0);
        for(int i = 1; i <= num; i++)
        {
        	BigDecimal a = new BigDecimal(new BigInteger(i+""));
            sum =sum.multiply(a);
        }
        return sum;
    }
	/**
	 * 组合排序算法(回溯方法)
	 * @param str 需要排序的字符串
	 * @param n   号码的个数 如果为-1，则默认为str的长度
	 * @param m   要选的个数
	 * @return
	 */
	public static List<String> combineAppend(String str[], int n, int m,
			String composeCode) {
		if (n == -1) {
			n = str.length;
		}
		m = m > n ? n : m;
		List<String> list = new ArrayList<String>();
		int[] order = new int[m + 1];
		for (int i = 0; i <= m; i++)
			order[i] = i - 1; // 注意这里order[0]=-1用来作为循环判断标识
		//int count = 0;
		int k = m;
		boolean flag = true; // 标志找到一个有效组合
		while (order[0] == -1) {
			if (flag){ // 输出符合要求的组合
				StringBuffer sb = new StringBuffer();
				for (int j = 1; j <= m; j++) {
					//count++;
					if (j != m) {
						sb.append(str[order[j]] + composeCode);
					} else {
						sb.append(str[order[j]]);
					}
				}
				flag = false;
				list.add(sb.toString());
			}
			order[k]++; // 在当前位置选择新的数字
			if (order[k] == n) {// 当前位置已无数字可选，回溯
				order[k--] = 0;
				continue;
			}
			if (k < m) {// 更新当前位置的下一位置的数字
				order[++k] = order[k - 1];
				continue;
			}
			if (k == m) flag = true;
		}
		return list;
	}
	
	/**排列*/
	public static List<String> permutation(String[] str,int count,String composeCode){
		List<String> result=new ArrayList<String>();
		if(count==0)return result;
		int[] indexs=new int[str.length];
		for(int i=0;i<indexs.length;i++){
			indexs[i]=i;
		}
		List<int[]> temp=MathUtil.permutation(indexs, count);
		for(int[] no:temp){
			String s=str[no[0]];
			for(int i=1;i<no.length;i++){
				s+=composeCode+str[no[i]];
			}
			result.add(s);
		}
		return result;
	}
	
	/**排列*/
	public static List<int[]> permutation(int[] a, int count) {
		if (a != null && count >= 0 && count <= a.length) {
			List<int[]> result = new ArrayList<int[]>();
			perm(result,a, 0, count);
			return result;
		}
		return new ArrayList<int[]>();
	}

	private static void perm(List<int[]> result,int[] a, int start, final int count) {
		if (start == count) {
			int[] temp=new int[count];
			for (int i = 0; i < count; i++) {
				temp[i]=a[i];
			}
			result.add(temp);
		} else {
			for (int i = start; i < a.length; i++) {
				swap(a, start, i);
				perm(result,a, start + 1, count);
				swap(a, start, i);
			}
		}
	}

	private static void swap(int[] a, int i, int j) {
		int t = a[i];
		a[i] = a[j];
		a[j] = t;
	}
	
	/**生成一个随机密码*/
	public static final String randomPassword(int m) {
		String code="";
		for(int i=0;i<m;i++){
			code+="0";
		}
		DecimalFormat df = new DecimalFormat(code);
		double temp=Math.random()*Math.pow(10, m);
		return df.format(temp);
	}
}
